package com.xmb.wcapi.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xmb.wcapi.entity.SysUser;
import com.xmb.wcapi.service.ISysUserService;

@Component
public class BeanUtil {

	private static ISysUserService iSysUserService;

	@Autowired
	public void setUserApi(ISysUserService iSysUserService) {
		BeanUtil.iSysUserService = iSysUserService;
	}

	/**
	* 将obj转换为对象
	* @param obj
	* @param cls
	* @return
	*/
	public static <T> T parseObjToBean(Object obj, Class<T> cls) {
		if(obj instanceof String) {
			return JSONObject.parseObject(obj.toString(), cls);
		};
		return JSONObject.parseObject(JSONObject.toJSONString(obj), cls);
	}
	
	public static <T> List<T> parseObjToList(Object obj, Class<T> cls) {
		if(obj instanceof String){
			return JSONObject.parseArray(obj.toString(),cls);
		}
		return JSONObject.parseArray(JSONObject.toJSONString(obj),cls);
	}
	
	/**
	* 千分位方法
	* @param text
	* @return
	*/
	public static String fmtMicrometer(String text){
		DecimalFormat df = null;
		if(text.indexOf(".") > 0){
			if(text.length() - text.indexOf(".")-1 == 0){
				df = new DecimalFormat("###,##0.");
			}else if(text.length() - text.indexOf(".")-1 == 1){
				df = new DecimalFormat("###,##0.0");
			}else{
				df = new DecimalFormat("###,##0.00");
			}
		}else{
			df = new DecimalFormat("###,##0");
		}
		double number = 0.0;
		try {
			number = Double.parseDouble(text);
		} catch (Exception e) {
			number = 0.0;
			System.out.println("数字千分位化转换异常");
		}
		return df.format(number);
	}
	
	/**
	 * list拷贝
	 * @param list
	 * @param tClass
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> List copyList(List<T> list, Class tClass) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList();
        }
        return JSON.parseArray(JSON.toJSONString(list), tClass);
    }
 
	/**
	 * map拷贝
	 * @param map
	 * @return
	 */
    @SuppressWarnings("rawtypes")
	public static Map<String, Object> copyMap(Map map) {
        return JSON.parseObject(JSON.toJSONString(map));
    }

	/**
	 * 获取对象属性值
	 * @param fieldName
	 * @param o
	 * @return
	 */
	public static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter);
            Object value = method.invoke(o);
            return value;
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
	}
    
	/**
	 * 设置对象属性值
	 * @param fieldName
	 * @param o
	 * @return
	 */
	public static void setFieldValueByName(String fieldName, String value, Object o) {
		try {
			Field field = o.getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			Type genericType = field.getGenericType();
            if (genericType.getTypeName().contains("String")){
            	field.set(o,value);
            }
            if (genericType.getTypeName().contains("Double")){
            	field.set(o,Double.parseDouble(value));
            }
            if (genericType.getTypeName().contains("Integer")){
            	field.set(o,Integer.parseInt(value));
            }
            if (genericType.getTypeName().contains("Date")){
                Date date = getDateByStr(value);
                field.set(o,date);
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
     * 字符串转时间
     * @param dateStr
     * @return
     */
    private static Date getDateByStr(String dateStr){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }

	/**
	 * 根据属性，获取get方法
	 * @param obj 对象
	 * @param name 属性名
	 * @return
	 * @throws Exception
	 */
	public static Object getMethod(Object obj , String name)throws Exception{
		Method[] m = obj.getClass().getMethods();
		for(int i = 0;i < m.length;i++){
			if(("get"+name).equalsIgnoreCase(m[i].getName())){
				return m[i].invoke(obj);
			}
		}
		return null;
	}

	/**
	 * 给对象属性设值
	 * @param obj
	 * @param filed
	 * @param value
	 * @throws Exception
	 */
	public static void setMethod(Object obj , String filed, Object value) throws Exception {
		Class<?> clazz = obj.getClass();
		String methodName = "set" + filed.substring(0,1).toUpperCase()+filed.substring(1);
		Method method =  clazz.getDeclaredMethod(methodName, obj.getClass().getDeclaredField(filed).getType());
		method.invoke(obj, value);
	}
	
	public static void dateFormat(Object o, Map<String, String> map) throws Exception {
		Field[] fields=o.getClass().getDeclaredFields();
		for(Field f : fields){
			if(f.getType().toString().equals("class java.util.Date")){
				if(getMethod(o,f.getName()) != null){
					map.put(f.getName(), DateUtil.getDateTimeFormat((Date) getMethod(o,f.getName())));
				}
			}else if(f.getType().toString().equals("class java.lang.Boolean")){
				if(getMethod(o,f.getName()) != null) {
					map.put(f.getName(), (Boolean) getMethod(o, f.getName()) ? "是" : "否");
				}
			}
			if(f.getName().equals("createUser") && getMethod(o,f.getName()) != null){
				SysUser user = iSysUserService.getById(getMethod(o, f.getName()).toString());
				map.put(f.getName(), user.getUserName());
			}
		}
	}
}
